#ifndef THREADPOOL_H
#define THREADPOOL_H

#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <future>
#include <atomic>

class ThreadPool {
public:
    // 构造函数，初始化线程池
    explicit ThreadPool(size_t threadCount)
        : stopFlag(false) {
        for (size_t i = 0; i < threadCount; ++i) {
            workers.emplace_back([this] {
                while (true) {
                    std::function<void()> task;

                    {
                        std::unique_lock<std::mutex> lock(queueMutex);
                        condition.wait(lock, [this] {
                            return stopFlag || !tasks.empty();
                        });

                        if (stopFlag && tasks.empty()) {
                            return; // 线程退出
                        }

                        task = std::move(tasks.front());
                        tasks.pop();
                    }

                    // 执行任务
                    task();
                }
            });
        }
    }

    // 禁止拷贝和赋值
    ThreadPool(const ThreadPool&) = delete;
    ThreadPool& operator=(const ThreadPool&) = delete;

//#if __cplusplus == 201103L
    //std::cout << "C++11 is supported." << std::endl;
//#elif __cplusplus == 201402L
    //std::cout << "C++14 is supported." << std::endl;
//#if __cplusplus == 201703L


//#elif __cplusplus == 202002L
    //std::cout << "C++20 is supported." << std::endl;
//#elif __cplusplus >= 202311L
    //std::cout << "C++23 or later is supported." << std::endl;
//#else
    //std::cout << "Older C++ standard is supported." << std::endl;
//#endif

#if __cplusplus > 201402L
    //std::cout << "C++11 is supported." << std::endl;
    // 提交任务到线程池
    template <typename F, typename... Args>
    auto submit(F&& f, Args&&... args) -> std::future<typename std::invoke_result<F, Args...>::type>
    {
        using ReturnType = typename std::invoke_result<F, Args...>::type;

        auto task = std::make_shared<std::packaged_task<ReturnType()>>(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...));

        std::future<ReturnType> result = task->get_future();

        {
            std::unique_lock<std::mutex> lock(queueMutex);

            if (stopFlag) {
                throw std::runtime_error("ThreadPool is stopped");
            }

            tasks.emplace([task]() { (*task)(); });
        }

        condition.notify_one();
        return result;
    }

#else
    template <typename F, typename... Args>
    void submit(F&& f, Args&&... args) {
        auto task = std::bind(std::forward<F>(f), std::forward<Args>(args)...);

        {
            std::unique_lock<std::mutex> lock(queueMutex);
            if(stopFlag)
                throw std::runtime_error("enqueue on stopped ThreadPool");

            tasks.emplace(task);
        }
        condition.notify_one();
    }
#endif



    // 析构函数，清理线程池
    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            stopFlag = true;
        }

        condition.notify_all();

        for (std::thread& worker : workers) {
            if (worker.joinable()) {
                worker.join();
            }
        }
    }

private:
    std::vector<std::thread> workers;               // 工作线程
    std::queue<std::function<void()>> tasks;        // 任务队列
    std::mutex queueMutex;                          // 队列互斥锁
    std::condition_variable condition;             // 条件变量
    std::atomic<bool> stopFlag;                     // 停止标志
};

#endif // THREADPOOL_H
